SWEP.Author			= "Hxrmn"
SWEP.Contact		= ""
SWEP.Purpose		= "A Grappling Hook"
SWEP.Instructions	= "Left click to fire"

SWEP.Spawnable			= true
SWEP.AdminSpawnable		= false	

SWEP.PrintName			= "Grappling Hook"			
SWEP.Slot				= 4
SWEP.SlotPos			= 0
SWEP.DrawAmmo			= false
SWEP.DrawCrosshair		= true
SWEP.ViewModel			= "models/weapons/v_superphyscannon.mdl"
SWEP.WorldModel			= "models/weapons/w_physics.mdl"

local sndPowerUp		= Sound("weapons/crossbow/hit1.wav")
local sndPowerDown		= Sound("Airboat.FireGunRevDown")
local sndShot			= Sound("weapons/357/357_fire2.wav")

function SWEP:Initialize()

	nextshottime = CurTime()
	self:SetWeaponHoldType( "smg" )
	
end

function SWEP:Think()

	if (!self.Owner || self.Owner == NULL) then return end
	
	if ( self.Owner:KeyPressed( IN_ATTACK ) ) then
	
		self:StartAttack()
		
	elseif ( self.Owner:KeyDown( IN_ATTACK ) ) then
	
		self:UpdateAttack()
		
	elseif ( self.Owner:KeyReleased( IN_ATTACK ) ) then
	
		self:EndAttack( true )
	
	end
	
	if ( self.Owner:KeyDown( IN_ATTACK2 ) ) then
	
		self:Attack2()
		
	end
	
--if(self.LastPos == nil or self.NextTrail == nil) then
--	self.LastPos = self.Owner:GetPos()
--	self.NextTrail = 0
--end
--		if(self.NextTrail < CurTime()) then
--			local vec = self.Owner:GetPos() + Vector(0,0,2)
--			if(self.LastPos ~= vec) then
--				local effectdata = EffectData()
--					effectdata:SetOrigin( vec )
--					effectdata:SetStart( self.LastPos )
--					effectdata:SetAttachment( 0 )
--					effectdata:SetEntity( self.Owner )
--				util.Effect( "playertrace", effectdata )
--			end
--		self.LastPos = vec
--		self.NextTrail = CurTime() + .1
--		end
--self.Owner:Trail()


end

function SWEP:Attack2()
	if(nextshottime < CurTime()) then
		self:ShootBulletEx( 1000000, 1, 0, 0 )
		//self:ShootBulletEx( 50, 5, .1, 0 )
		nextshottime = CurTime()+1
		//if(CLIENT) then
			self.Weapon:EmitSound( sndShot )
		//end
	end
end

function SWEP:ShootBulletEx( damage, num_bullets, aimcone, tracerfreq )

	//local tr = self.Owner:GetEyeTrace()
	
	local bullet = {}
	bullet.Num 		= num_bullets
	bullet.Src 		= self.Owner:GetShootPos()			// Source
	bullet.Dir 		= self.Owner:GetAimVector()			// Dir of bullet
	bullet.Spread 	= Vector( aimcone, aimcone, 0 )		// Aim Cone
	bullet.Tracer	= tracerfreq						// Show a tracer on every x bullets 
	bullet.Force	= 100								// Amount of force to give to phys objects
	bullet.Damage	= damage
	bullet.AmmoType = "Pistol"
	bullet.TracerName 	= "Tracer"
	bullet.Callback    = function ( a, b, c ) self:BulletCallback( a, b, c ) end
	
	self.Owner:FireBullets( bullet )
	
	self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) 		// View model animation
	self.Owner:MuzzleFlash()							// Crappy muzzle light
	self.Owner:SetAnimation( PLAYER_ATTACK1 )			// 3rd Person Animation
	
end

function SWEP:BulletCallback( attacker, tr, dmginfo )

		util.BlastDamage( self.Weapon, self.Owner, tr.HitPos, 180, 40 )

		local effectdata = EffectData()
			effectdata:SetOrigin( tr.HitPos )
			effectdata:SetStart( self.Owner:GetShootPos() )
			effectdata:SetAttachment( 1 )
			effectdata:SetEntity( self.Weapon )
		util.Effect( "GrappleTracer", effectdata )

		/*	local vm = attacker:GetViewModel()
			if (!vm || vm == NULL) then return end
			local attachment = vm:GetAttachment( 1 )
			local StartPos = attachment.Pos

		if ( !ViewModel ) then
		// If we're viewing another player we start at their weapon
		
			local vm = attacker:GetActiveWeapon()
			if (!vm || vm == NULL) then return end
			local attachment = vm:GetAttachment( 1 )
			StartPos = attachment.Pos
		
		end*/

end

function SWEP:DoTrace( endpos )
	local trace = {}
		trace.start = self.Owner:GetShootPos()
		trace.endpos = trace.start + (self.Owner:GetAimVector() * 14096)
		if(endpos) then trace.endpos = (endpos - self.Tr.HitNormal * 7) end
		trace.filter = { self.Owner, self.Weapon }
		
	self.Tr = nil
	self.Tr = util.TraceLine( trace )
end

function SWEP:StartAttack()

	if (SERVER) then
		
		if (!self.Beam) then
			--grapple_beam
			self.Beam = ents.Create( "trace1" )
				self.Beam:SetPos( self.Owner:GetShootPos() )
			self.Beam:Spawn()
		end
		
		self.Beam:SetParent( self.Owner )
		self.Beam:SetOwner( self.Owner )
	
	end
	
	self:DoTrace()
	self.speed = 3000
	self.startTime = CurTime()
	self.endTime = CurTime() + self.speed
	self.dt = -1
	
	if (SERVER && self.Beam) then
		self.Beam:GetTable():SetEndPos( self.Tr.HitPos )
	end
	
	self:UpdateAttack()
	
	self.Weapon:EmitSound( sndPowerDown )
	
end

function SWEP:UpdateAttack()

	self.Owner:LagCompensation( true )
	
	if (!endpos) then endpos = self.Tr.HitPos end
	
	if (SERVER && self.Beam) then
		self.Beam:GetTable():SetEndPos( endpos )
	end

	lastpos = endpos
	
	
			if ( self.Tr.Entity:IsValid() ) then
			
					endpos = self.Tr.Entity:GetPos()
					if ( SERVER ) then
					self.Beam:GetTable():SetEndPos( endpos )
					end
			
			end
			
			local vVel = (endpos - self.Owner:GetPos())
			local Distance = endpos:Distance(self.Owner:GetPos())
			
			local et = (self.startTime + (Distance/self.speed))
			if(self.dt != 0) then
				self.dt = (et - CurTime()) / (et - self.startTime)
			end
			if(self.dt < 0) then
				self.Weapon:EmitSound( sndPowerUp )
				self.dt = 0
			end
			
			if(self.dt == 0) then
			zVel = self.Owner:GetVelocity().z
			vVel = vVel:GetNormalized()*(math.Clamp(Distance,0,7))
				if( SERVER ) then
				local gravity = GetConVarNumber("sv_Gravity")
				//self.Tr.Entity:SetVelocity(vVel*-1000)
				vVel:Add(Vector(0,0,(gravity/100)*1.5))
				if(zVel < 0) then
					vVel:Sub(Vector(0,0,zVel/100))
				end
				self.Owner:SetVelocity(vVel)
				end
			end
	
	endpos = nil
	
	self.Owner:LagCompensation( false )
	
end

function SWEP:EndAttack( shutdownsound )
	
	if ( shutdownsound ) then
		self.Weapon:EmitSound( sndPowerDown )
	end
	
	if ( CLIENT ) then return end
	if ( !self.Beam ) then return end
	
	self.Beam:Remove()
	self.Beam = nil
	
end

function SWEP:Holster()
	self:EndAttack( false )
	return true
end

function SWEP:OnRemove()
	self:EndAttack( false )
	return true
end


function SWEP:PrimaryAttack()
end

function SWEP:SecondaryAttack()
end

